//! 通用谓词
//! + [predicate::function] 指定一个闭包或函数作为断言
//! + [predicate::in_iter] 指定的值必须在迭代器内
//! + [predicate::in_iter(...).sort] 对重复调用的谓词进行优化
//! + [predicate::in_hash] 对重复调用的谓词进行优化
//! 
//! 组合器
//! + [pred_a.and(pred_b)] 两个断言必须都成功
//! + [pred_a.or(pred_b)] 至少有一个断言成功
//! + [pred_a.not()] 断言必须失败
//! 
//! String断言
//! + [predicate::str::is_empty] 指定的字符串必须为空即""
//! + [predicate::path::eq_file(...).utf8]  指定的字符串必须等于给定文件的内容
//! + [predicate::str::diff] 和eq相同，但报告有差异
//! + [predicate::str::starts_with] 指定的值必须以给定的值开始
//! + [predicate::str::ends_with] 指定的值必须以给定的值结束
//! + [predicate::str::contains] 指定的值必须以包含给定的值
//! + [predicate::str::contains(...).count] 指定的值必须以包含给定的值，且包含count给定的次数
//! + [predicate::str::is_match] 指定的值必须匹配给定的正则
//! + [predicate::str::is_match(...).count] 指定的值必须匹配给定的正则，且包含count给定的次数
//! + [str_pred.trim] 在传递给 str_pred 之前删除空白字符。
//! + [str_pred.normalize] 在传递给 str_pred 之前规范化行结束符
//! + [bytes_pred = str_pred.from_utf8()] 重用字符串谓词在其他上下文中，如文件系统。
//! 
//! 文件系统断言
//! + [predicate::path::exists] 指定的路径必须存在
//! + [predicate::path::missing] 指定的路径必须不存在
//! + [predicate::path::is_dir] 指定的路径是目录
//! + [predicate::path::is_file] 指定的路径是文件
//! + [predicate::path::is_symlink] 指定的路径是一个符号链接
//! + [path_pred = predicate::path::eq_file] 指定的路径内容必须等于给定文件的内容
//! + [path_pred = bytes_pred.from_file_path] 指定的路径内容必须等于 bytes_pred

#![allow(unused)]
use predicates::prelude::*;

/// 始终返回`true`或`false`
/// 
/// [predicate::always]方法返回[BooleanPredicate]计算结果始终为他`true`
/// [predicate::never]方法返回[BooleanPredicate]计算结果始终为他`false`
fn always_or_never(){
    let always_true = predicate::always();
    assert_eq!(true, always_true.eval(&5));
    let always_false = predicate::never();
    assert_eq!(false, always_false.eval(&5));
}

/// 可用于实现 [PartialOrd] 和 [PartialEq] 特征。
/// 
/// 以下示例使用`lt`，但 `eq`、`ne`、`le`、`gt`、`ge` 也可用。
fn ord_or_eq(){
    let less_than_ten = predicate::lt(10);
    assert_eq!(true, less_than_ten.eval(&9));
    assert_eq!(false, less_than_ten.eval(&11));
}

/// 验证一个[&str]是否为`empty`即`""`
fn is_empty(){
    let is_empty = predicate::str::is_empty();
    assert_eq!(true, is_empty.eval(""));
    assert_eq!(false, is_empty.eval("123"));
}

/// 将闭包或函数转成[FnPredicate]并且可以组合其他的[Predicate]
fn function(){
    let bound = 5;
    let predicate_fn = predicate::function(|&x| x >= bound);
    let between_5_and_10 = predicate_fn.and(predicate::le(10));
    assert_eq!(true, between_5_and_10.eval(&7));
    assert_eq!(false, between_5_and_10.eval(&3));
    assert_eq!(false, between_5_and_10.eval(&11));
}

/// 指定的值必须在迭代器内
fn in_iter(){
    let in_iter = predicate::in_iter([1, 2, 3]).sort();
    assert_eq!(true, in_iter.eval(&3));
    assert_eq!(false, in_iter.eval(&4));
}

/// 浮点类型的等于
fn is_close(){
    let is_close = predicate::float::is_close(3.2);
    assert_eq!(true, is_close.eval(&3.2));
}
fn main() {
    is_close()
}
